#include "Semaforo.h"
#include <iostream>


Semaforo :: Semaforo ( const char* archivo, char letra, int valorInicial ) {

	key_t clave = ftok ( archivo,letra );
	this->id = semget ( clave,1,0666 | IPC_CREAT | IPC_EXCL ); /* si no existe crea el semaforo */

	if (this->id > 0)
	{
		this->inicializar (valorInicial);
	}
	else
	{
		this->id = semget ( clave,1,0666 | IPC_CREAT);
		if (this->id <= 0 )
		{
			std::cout<<getpid()<<": error creando semaforo con la clave: "<<clave<<std::endl;
		}
	}
}

Semaforo::~Semaforo() {
}


int Semaforo :: inicializar (int valorInicial) {

	union semnum {
		int val;
		struct semid_ds* buf;
		ushort* array;
	};

	int resultado = -1;

	if (this->id > 0)
	{
		semnum init;
		init.val = valorInicial;
		resultado = semctl ( this->id,0,SETVAL,init );
	}

	return resultado;
}

int Semaforo :: wait () {

	int resultado = -1;

	if (this->id > 0)
	{
		struct sembuf operacion;

		operacion.sem_num = 0;	// numero de semaforo
		operacion.sem_op  = -1;	// restar 1 al semaforo
		operacion.sem_flg = SEM_UNDO;

		resultado = semop ( this->id,&operacion,1 );
	}
	return resultado;
}

int Semaforo :: signal () {

	int resultado = -1;
	if (this->id > 0)
	{
		struct sembuf operacion;

		operacion.sem_num = 0;	// numero de semaforo
		operacion.sem_op  = 1;	// sumar 1 al semaforo
		operacion.sem_flg = SEM_UNDO;

		resultado = semop ( this->id,&operacion,1 );
	}

	return resultado;
}

void Semaforo :: eliminar () {
	semctl ( this->id,0,IPC_RMID );
	this->id = -1;
}



